﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using log4net;
using log4net.Config;
using Logic;
using oAuth;

namespace BLL
{
    public partial class Users
    {
        static ILog logger = LogManager.GetLogger("default");
        
        internal static bool ValidateGoogleSig()
        {
            oAuth.OAuthBase oauth = new oAuth.oAuthClarizen(Logic.GoogleGadget.GadgetList, HttpContext.Current.Request);
            if (string.IsNullOrEmpty(oauth.ConsumerSecret))
                return false;
            
            var req = HttpContext.Current.Request;
            return oauth.ValidateSignature(req);
        }
        
        public static String GetGoogleID(Boolean useValidatedSig = true, Boolean useSession = false)
        {
            var req = HttpContext.Current.Request;

            if (!string.IsNullOrEmpty(req["opensocial_viewer_id"]) || useValidatedSig)
                return req["opensocial_viewer_id"];

            else if (HttpContext.Current.Session[Logic.Constants.googleID] != null)
                return HttpContext.Current.Session[Logic.Constants.googleID].ToString();

            else if(!string.IsNullOrEmpty(req[Logic.Constants.googleID]) && !useSession)
                return BLL.Encryption.Decrypt(req.QueryString[Logic.Constants.googleID]);

            return null;
        }

        public static String GetClarizenSession()
        {
            return HttpContext.Current.Session["clarizenSession"] != null ?
                HttpContext.Current.Session["clarizenSession"] as String :
                "";
        }

        public static void SetClarizenSession(String session, int? userID)
        {
            HttpContext.Current.Session["clarizenSession"] = session;
            CurrentUserID = userID;
        }

        public static Boolean EnsureSession(BO.User user)
        {
            return EnsureSession(user, false);
        }

        public static Boolean EnsureSession(BO.User user, Boolean reset)
        {
            if (string.IsNullOrEmpty(user.ClarizenSession) || reset)
            {
                oAuth.oAuthClarizen oauth = oAuthClarizen.Get();
                oauth.Token = user.Token;
                try
                {
                    var session = oauth.GetSessionKey();
                    user.ClarizenSession = session;
                    user.Update();
                    Log.Write("success EnsureSession");
                }
                catch (Exception e)
                {
                    Log.Write("Error EnsureSession");
                    Log.Write("Error EnsureSession: " + user.GoogleID);
                    if (e.Message.Contains("Unauthorized"))
                    {
                        Log.Write("Error EnsureSession1");
                        user.ClarizenSession = null;
                        user.Token = null;
                        Log.Write("Error EnsureSession2");

                        user.Update();
                        SetClarizenSession("", null);
                        Log.Write("Error EnsureSession3");

                        return false;
                    }
                    else
                    {
                        Log.Write("Error1 " + e.Message);
                        user.Update();
                        return false;
                    }
                }


            }
            SetClarizenSession(user.ClarizenSession, user.ID);
            return true;
        }

        //public static Boolean EnsureSession(String token, Boolean reset)
        //{
        //    if (!EnsureSession() || reset)
        //    {
        //        oAuth.oAuthClarizen oauth = oAuthClarizen.Get();
        //        oauth.Token = token;
        //        try
        //        {
        //           var session = oauth.GetSessionKey();
        //           SetClarizenSession(session, null);
        //           return true;
        //        }
        //        catch (Exception e)
        //        {
        //           return false;
        //        }
        //    }

        //    return true;
        //}

        public static Boolean EnsureSession()
        {
            return !string.IsNullOrEmpty(GetClarizenSession()) && CurrentUserID.HasValue;
        }

        public static bool Login(string tbUserName, string tbPassword, String container)
        {
            Logic.LoginComponent.LoginResponse lr;
            return Login(tbUserName, tbPassword, container, out lr);
        }

        public static bool Login(string tbUserName, string tbPassword, String container, out Logic.LoginComponent.LoginResponse loginResponse)
        {
            Logic.LoginComponent loginService = new Logic.LoginComponent();
            loginResponse = loginService.Login(tbUserName, tbPassword);
            if (loginService.Service.Session == null)
                return false;

            

            var user = Users.Get().Where(Columns.ClarizenUserID, Actions.Equal, loginResponse.LoginResult.UserId).SelectOne();
            if (user == null)
            {
                user = new BO.User
                {
                    ClarizenUserID = loginResponse.LoginResult.UserId,
                    ClarizenSession = loginService.Service.Session.ID,
                    UserName = tbUserName
                };
                var remoteUser = new QueryComponent(user.ClarizenSession).GetCurrentUser(user);
                user.UserName = remoteUser.DisplayName;
                user.Insert();
            }
            else
            {
                user.ClarizenSession = loginService.Service.Session.ID;
                user.Update();
            }

            SetClarizenSession(user.ClarizenSession, user.ID);
            return EnsureSession();
        }

        public static void Logout()
        {
            //var user = GetCurrentUser();
            //if (user != null)
            //{
            //    user.ClarizenSession = null;
            //    user.Token = null;
            //    user.Update();
            //}
            SetClarizenSession("", null);
        }

        public static int? CurrentUserID
        {
            get { return HttpContext.Current.Session["userID"] as int?; }
            set { HttpContext.Current.Session["userID"] = value; }
        }

        public static string CurrentClarizenID
        {
            get 
            {
                var user = GetCurrentUser();
                return user != null? user.ClarizenUserID: null; 
            }
        }

        public static Logic.ClarizenObjects.User GetClarizenUser()
        {
            var localUser = GetCurrentUser();

            if (localUser == null)
                return null;

            if (!string.IsNullOrEmpty(localUser.UserName))
                return new Logic.ClarizenObjects.User { ID = new Logic.ClarizenSvc.EntityId { TypeName = "User", Value = localUser.ClarizenUserID }, Name = localUser.UserName };
            if (!string.IsNullOrEmpty(localUser.ClarizenUserID))
                return new QueryComponent().GetCurrentUser(localUser);
            else return null;
        }


        public static BO.User GetCurrentUser()
        {
            if (HttpContext.Current.Items["user"] == null)
                HttpContext.Current.Items["user"] = Users.GetByID(CurrentUserID);

            return HttpContext.Current.Items["user"] as BO.User;
        }

        public static String GetAuthorizationLink(String goTo = "", Boolean logout = false)
        {
            if (Constants.IsGmail)
            {

                oAuthClarizen oAuth = oAuthClarizen.Get();
                oAuth.Identifier = HttpUtility.UrlEncode(HttpUtility.UrlEncode(BLL.Encryption.Encrypt(BLL.Users.GetGoogleID())));
                return oAuth.AuthorizationLinkGet();
            }
            else
            {
                if (string.IsNullOrEmpty(goTo))
                    goTo = HttpContext.Current.Request.UrlReferrer.ToString();
                return Logic.Constants.CurrentUrl + "/login/login?" + "goto=" + HttpUtility.UrlEncode(goTo.Replace("accessToken=", "AA=")) + (logout ? "&logout=1" : "");
            }
        }
    }
}
